﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using Database.Classes;
using System.Collections.Generic;
using System.Text;


public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void UpdatePlanets()
    {

        Dictionary<string, double> commands = new Dictionary<string, double>();
        int intervalTime = int.Parse(GetConfigurationForOption("SmallUpdateInterval"));//in seconds
        double growthBonus = double.Parse(GetConfigurationForOption("GrowthBonus"));
        double prodBonus = double.Parse(GetConfigurationForOption("ProductionBonus"));
        Dictionary<int, int> TABonus = TABonuses();

        try
        {
            using (SqlConnection conn = new SqlConnection(StaticMethods.ConnectionString()))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand(
 @"SELECT     dbo.Planets.PlanetID, dbo.Planets.SystemID, dbo.Planets.OwnerID, dbo.Planets.FleetOwnerID, 
                      dbo.Planets.Farms, dbo.Planets.Factories, dbo.Planets.Cybernets, 
                      dbo.Planets.Labs, dbo.Planets.Starbase, dbo.Planets.PopulationLevel, dbo.Planets.PopToNextLevel, dbo.Planets.ProductionPoints, 
                      dbo.Players.Social, dbo.Players.ArtifactID, dbo.Players.Growth, dbo.Players.Production
FROM         dbo.Planets INNER JOIN
                      dbo.Players ON dbo.Planets.OwnerID = dbo.Players.PlayerId
WHERE     (dbo.Planets.OwnerID > 1)", conn))
                {
                    SqlDataReader rdr = cmd.ExecuteReader();


                    while (rdr.Read())
                    {
                        int pId = int.Parse(rdr["PlanetID"].ToString());
                        int sId = int.Parse(rdr["SystemID"].ToString());
                        int owner = int.Parse(rdr["OwnerID"].ToString());
                        //update growth
                        int maxPop, currentPopulation, farms;
                        double popToNextLevel;
                        double bonus;
                        try
                        {
                            string aId = rdr["ArtifactID"] as string;
                            //update production
                            bonus = 1.0 + int.Parse(rdr["Production"].ToString()) * prodBonus + TABonus[owner] * 1.0 / 100.0;
                            if (aId != null)
                            {
                                switch (aId)
                                {
                                    case "CS":
                                        bonus = bonus + 0.1; break;
                                    case "RF":
                                        bonus = bonus + 0.2; break;
                                    case "NF":
                                        bonus = bonus + 0.3; break;
                                    case "STr":
                                        bonus = bonus - 0.15; break;
                                    case "BHS":
                                        bonus = bonus - 0.1; break;
                                    case "AF":
                                        bonus -= 0.5; break;
                                }
                            }
                            double planetProduction = 1 + (int)double.Parse(rdr["Factories"].ToString()) + int.Parse(rdr["PopulationLevel"].ToString());
                            double outpp = planetProduction * bonus;
                            if (outpp < 0)
                                outpp = 0.01;
                            commands.Add("Update dbo.planets Set ProductionPoints = ProductionPoints + @val Where PlanetID = " + pId.ToString() + " and SystemId = " + sId.ToString(), outpp / (3600 / intervalTime));

                            maxPop = UserDefinedFunctions.MaxPopulationForPlanet((int)double.Parse(rdr["Social"].ToString())).Value;
                            if (int.Parse(rdr["PopulationLevel"].ToString()) == maxPop)
                                continue;

                            popToNextLevel = double.Parse(rdr["PopToNextLevel"].ToString());
                            farms = 1 + (int)double.Parse(rdr["Farms"].ToString());
                            currentPopulation = int.Parse(rdr["PopulationLevel"].ToString());
                            //get growth bonus
                            bonus = 1.0 + int.Parse(rdr["Growth"].ToString()) * growthBonus + TABonus[owner] * 1.0 / 100.0;
                            //get artifact bonus

                            if (aId != null)
                            {
                                switch (aId)
                                {
                                    case "E1":
                                        bonus = bonus + 0.1; break;
                                    case "E2":
                                        bonus = bonus + 0.2; break;
                                    case "E3":
                                        bonus = bonus + 0.3; break;
                                    case "STr":
                                        bonus = bonus + 0.2; break;
                                    case "BHS":
                                        bonus = bonus - 0.1; break;
                                    case "AF":
                                        bonus -= 0.9; break;
                                    case "MOT": bonus += 0.2; break;
                                }
                            }

                            double output = farms * 1.0 * bonus;
                            if (output < 0)
                                output = 0.01;
                            //InsertLog(DateTime.Now, "UpdatePlanets", "Updating planet: " + pId + " " + sId);
                            if (popToNextLevel * 1.0 - output / (3600.0 / intervalTime) <= 0) // add a pop
                            {
                                commands.Add("UPdate planets Set PopulationLevel = " + (currentPopulation + 1).ToString() + ", PopToNextLevel = @val Where PlanetID = " + pId.ToString() + " and SystemId = " + sId.ToString(), Equations.PopulationLevel(currentPopulation + 1));
                            }
                            else
                            {
                                commands.Add("UPdate planets Set  PopToNextLevel = PopToNextLevel - @val Where PlanetID = " + pId.ToString() + " and SystemId = " + sId.ToString(), farms * 1.0 * bonus / (3600.0 / intervalTime));

                            }

                        }
                        catch (Exception ex)
                        {
                            conn.Close();
                            InsertNews(8, DateTime.Now, ex.ToString());
                            return;
                        }
                    }
                    rdr.Close();
                }
            }
        }
        catch (Exception ex)
        {
            InsertNews(8, DateTime.Now, ex.ToString());
        }
        //InsertNews(8, DateTime.Now, "After update");
        //StringBuilder sb = new StringBuilder();
        //foreach (string s in commands.Keys)
        //    sb.Append(s).Append("<br/>\n");
        //InsertNews(8, DateTime.Now, sb.ToString());
        foreach (string s in commands.Keys)
        {
            try
            {
                ExecuteQuery(s, commands[s]);

            }
            catch (Exception ex)
            {
                InsertNews(8, DateTime.Now, s + "<br/>" + ex.ToString());
                throw new Exception(s, ex);
            }
        }

    }

    private static void ExecuteQuery(string s, double val)
    {
        using (SqlConnection conn = new SqlConnection(StaticMethods.ConnectionString()))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand(s, conn))
            {
                cmd.Parameters.Add("@val", SqlDbType.Float);
                cmd.Parameters["@val"].Value = val;
                cmd.ExecuteNonQuery();
            }
        }
    }
};
